package com.xing.lei.happy.utils;

import java.util.ArrayList;
import java.util.List;


public class Chain<T> {
	private T value;
	private Chain<T> prev;
	private Chain<T> next;

	public Chain() {
	}

	public Chain(T value) {
		this.value = value;
	}

	public T value() {
		return value;
	}

	public void value(T value) {
		this.value = value;
	}

	public Chain<T> prev() {
		return prev;
	}

	public boolean hasPrev() {
		return prev != null;
	}

	public void prev(Chain<T> chain) {
		if (chain != null) {
			chain.remove();
			chain.prev = prev;
			chain.next = this;
		}
		if (prev != null) {
			prev.next = chain;
		}
		prev = chain;
	}

	public Chain<T> next() {
		return next;
	}

	public boolean hasNext() {
		return next != null;
	}

	public void next(Chain<T> chain) {
		if (chain != null) {
			chain.remove();
			chain.next = next;
			chain.prev = this;
		}
		if (next != null) {
			next.prev = chain;
		}
		next = chain;
	}

	public void remove() {
		if (prev != null) {
			prev.next = next;
			prev = null;
		}
		if (next != null) {
			next.prev = prev;
			next = null;
		}
	}

	public Chain<T> first() {
		Chain<T> chain = this;
		while (chain.hasPrev()) {
			chain = chain.prev();
		}
		return chain;
	}

	public Chain<T> last() {
		Chain<T> chain = this;
		while (chain.hasNext()) {
			chain = chain.next();
		}
		return chain;
	}

	public List<Chain<T>> chains() {
		List<Chain<T>> list = new ArrayList<Chain<T>>();
		Chain<T> chain = null;
		list.add(chain = first());
		while (chain.hasNext()) {
			list.add(chain = chain.next());
		}
		return list;
	}

	public List<T> values() {
		List<T> list = new ArrayList<T>();
		Chain<T> chain = null;
		list.add((chain = first()).value());
		while (chain.hasNext()) {
			list.add((chain = chain.next()).value());
		}
		return list;
	}

	private void addChain(List<String> list, Chain<T> chain) {
		if (chain == this) {
			list.add("【" + chain.value() + "】");
		} else {
			list.add(ObjectUtils.toString(chain.value()));
		}
	}

	@Override
	public String toString() {
		List<String> list = new ArrayList<String>();
		Chain<T> chain = null;
		addChain(list, chain = first());
		while (chain.hasNext()) {
			addChain(list, chain = chain.next());
		}
		return list.toString();
	}
}